package common

import (
	"adminserver/global"
	"encoding/json"
	"fmt"
	"math"
	"net/url"
	"runtime"
	"strings"
	"time"

	"github.com/astaxie/beego/logs"
)

// URLJoin url拼接参数
func URLJoin(rawURL string, params map[string]string) string {
	newURL, _ := url.Parse(rawURL)
	query := ""
	values := newURL.Query()
	for key, val := range params {
		values.Add(key, val)
	}
	query = values.Encode()
	if query != "" {
		query = "?" + query
	}
	fragment := ""
	if newURL.Fragment != "" {
		fragment = "#" + newURL.Fragment
		if strings.Contains(newURL.Fragment, "?") {
			d := []rune(query)
			if d[0] == '?' {
				d[0] = '&'
				query = string(d)
			}
		}
	}
	buildURL := newURL.Scheme + "://" + newURL.Host + "" + newURL.Path + fragment + query
	return buildURL
}

func TimeZero(t time.Time) int64 {
	return time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, t.Location()).Unix()
}

func ParseTimeWithYmd(str string) time.Time {
	tempT, _ := time.ParseInLocation("2006-01-02", str, time.Local)
	return tempT
}

func TrustJson(obj interface{}) []byte {
	tempByte, _ := json.Marshal(obj)
	tempByte = IfInterface(tempByte == nil, []byte{}, tempByte).([]byte)
	return tempByte
}

// IfInterface cond ? a : b
func IfInterface(cond bool, a, b interface{}) interface{} {
	if cond {
		return a
	}
	return b
}

func IfInterfaceFunc(cond bool, a func() interface{}, b func() interface{}) interface{} {
	if cond {
		return a()
	}
	return b()
}

func TotalPage(totalRowsNum, eachPageRow int) int {
	totalpage := int(math.Ceil(float64(totalRowsNum) / float64(eachPageRow)))
	if totalRowsNum > 0 && totalpage == 0 {
		totalpage = 1
	}
	return totalpage
}

func InArray(need string, needArr []string) bool {
	for _, v := range needArr {
		if need == v {
			return true
		}
	}
	return false
}

func InArrayInt64(need int64, needArr []int64) bool {
	for _, v := range needArr {
		if need == v {
			return true
		}
	}
	return false
}

func RemoveDuplicate(arr []string) []string {
	resArr := make([]string, 0)
	tmpMap := make(map[string]interface{})
	for _, val := range arr {
		//判断主键为val的map是否存在
		if _, ok := tmpMap[val]; !ok {
			resArr = append(resArr, val)
			tmpMap[val] = nil
		}
	}
	return resArr
}

func RecoverPanic(fixer ...func(err interface{})) {
	if err := recover(); err != nil {
		stacks := GetStacks()
		logs.Critical(fmt.Sprintf("err: %s, stacks: %s", err, stacks))
		if len(fixer) > 0 {
			fixer[0](err)
		}
	}
}

// GetStacks ...
func GetStacks() string {
	var stack []string
	for i := 1; ; i++ {
		_, file, line, ok := runtime.Caller(i)
		if !ok {
			break
		}
		stack = append(stack, fmt.Sprintf("%s:%d", file, line))
	}
	joinStr := ", "
	if global.GVA_CONFIG.App.Mode == "local" { // 测试环境换行显示
		joinStr = "\r\n"
	}
	return strings.Join(stack, joinStr)
}
